<?php
//-------------------------------------------------------------------------------------------------------
    //require_once($config['adodb']['path'] . 'adodb-time.inc.php');

    require_once($config['app_dir'] . '/includes/object.class.php');
    require_once($config['app_dir'] . '/includes/db.class.php');
    require_once($config['app_dir'] . '/includes/date.class.php');
    require_once($config['app_dir'] . '/includes/number.class.php');
    //---------------------------------------------------------------------------------------------------
    class objIDParam extends objObject implements iErrorHandler, iDebug{
            public $id = false;
            protected $_error_str = array('no error');

        public function __construct() {
            $this->_getID();
        } //constructor

        public function ClassName() {
            return  __CLASS__;
        }//ClassName

        public function Dump() {
                echo "Dump \n<br>";
                echo "\n<br>ID : "; var_dump($this->id);
        } //dump
        //----------------------------------------------------------------------
        protected function _getID() {
            if ( !isset($_GET['id']) || empty($_GET['id']) ) {
                return false;
            } else $this->id = $_GET['id'];
            return $this->id;
        } //getID
    }// class IDParam
    //---------------------------------------------------------------------------------------------------
    class objStockParams extends objObject implements iErrorHandler, iDebug{
            public $trade = false;
            public $start = false;
            public $finish = false;
            public $system = false;
            public $forecast_id = false;

            public $t=false;
            protected $flag_unixtime = false;
            protected $flag_strict = true;

            protected $_error_str = array('no error',
                                          'Not set trade id or trade is not integer.',
                                          'Not set start of period.',
                                          'Not set finish of period.',
                                          'Start is greater or equal than finish.',
                                          'Not set system');

        function __construct($fUnixtime=false, $fStrict=true) {
            $this->flag_unixtime = $fUnixtime;
            $this->flag_strict = $fStrict;
            $this->Build();
        } //constructor

        protected function checkDates() {
            return $this->UnixtimeDate($this->start) < $this->UnixtimeDate($this->finish);
        }//checkDates

        public function Build() {
            if ( false === $this->_getTrade() && $this->flag_strict ) return ;
            if ( false === $this->_getStart() && $this->flag_strict ) return ;
            if ( false === $this->_getFinish() && $this->flag_strict ) return ;
            if ( $this->flag_strict &&  !$this->checkDates() ) {

                throw new Exception($this->Error(4));
                return ;
            }
            $this->_getT();
            $this->_getSystem();
            $this->_getForecastID();
        }//Build

        public function ClassName() {
            return  __CLASS__;
        }//ClassName

        public function GenID() {
            return md5(strval($this->trade) .'_'. strval($this->start) .'_'. strval($this->finish) .'_'. strval($this->t));
        } //GenID

        public function ReformatDate($date) {
            return DateConvert::Date2('Y-m-d', $date);//adodb_date2('Y-m-d', $date);
        }//ReformatDate

        public function UnixtimeDate($date) {
            return intval(DateConvert::Date2('U', $date)/*adodb_date2('U', $date)*/);
        }//UnixtimeDate

        public function Dump() {
            echo "Dump \n<br>";
            echo "\n<br>Trade : "; var_dump($this->trade);
            echo "\n<br>Start : "; var_dump($this->start);
            echo "\n<br>Finish : "; var_dump($this->finish);
            echo "\n<br>System : "; var_dump($this->system);
            echo "\n<br>ForecastID : "; var_dump($this->forecast_id);
            echo "\n<br>T : "; var_dump($this->t);
        } //dump
        //----------------------------------------------------------------------
        protected function _getTrade() {
            if ( !isset($_GET['trade']) || !is_numeric($_GET['trade']) || empty($_GET['trade']) ) {
                if( $this->flag_strict ) throw new Exception($this->Error(1));
                return false;
            } else {
                $this->trade = intval($_GET['trade']) ;
            }

            return $this->trade;
        } //getTrade

        protected function _getT() {
            if ( !isset($_GET['t']) || !is_numeric($_GET['t']) || empty($_GET['t']) ) {
                return false;
            } else $this->t = intval($_GET['t']) ;
            return $this->t;
        } //getT

        protected function _getStart() {
            if ( !isset($_GET['start']) || empty($_GET['start']) ) {
                if( $this->flag_strict ) throw new Exception($this->Error(2));
                return false;
            } else {
                if( $this->flag_strict ) $this->start = $this->ReformatDate($_GET['start']);
                if( $this->flag_unixtime ) $this->start = $this->UnixtimeDate($this->start);
            }
            return $this->start;
        } //getStart

        protected function _getFinish() {
            if ( !isset($_GET['finish']) || empty($_GET['finish']) ) {
                if( $this->flag_strict ) throw new Exception($this->Error(3));
                return false;
            } else  {
                $this->finish = $this->ReformatDate($_GET['finish']);
                if( $this->flag_unixtime ) $this->finish = $this->UnixtimeDate($this->finish);
            }
            return $this->finish;
        } //getFinish

        protected function _getSystem() {
            if ( !isset($_GET['system']) || empty($_GET['system']) ) {
                return false;
            } else  $this->system = $_GET['system'];
            return $this->system;
        } //getSystem

        protected function _getForecastID() {
            if ( !isset($_GET['forecast_id']) || empty($_GET['forecast_id']) ) {
                return false;
            } else  $this->forecast_id = $_GET['forecast_id'];
            return $this->forecast_id;
        } //getForecastID

    } //class objStockParams

    //---------------------------------------------------------------------------------------------------
    class objUStockParams extends objStockParams implements iErrorHandler, iDebug{

        public function ClassName() {
            return  __CLASS__;
        }//ClassName

        protected function checkDates() {
            return $this->start < $this->finish;
        }//checkDates

        protected function _getStart() {
            if ( !isset($_GET['start']) || empty($_GET['start']) || !is_numeric($_GET['start'])) {
                if( $this->flag_strict ) throw new Exception($this->Error(2));
                return false;
            } else {
                $this->start = intval($_GET['start']);
            }
            return $this->start;
        } //getStart

        protected function _getFinish() {
            if ( !isset($_GET['finish']) || empty($_GET['finish']) || !is_numeric($_GET['finish']) ) {
                if( $this->flag_strict ) throw new Exception($this->Error(3));
                return false;
            } else  {
                $this->finish = intval($_GET['finish']);
            }
            return $this->finish;
        } //getFinish

    } //class objUStockParams

    //-----------------------------------------------------------------------------------------------
    class objStockValidationPeriod {
            protected $_trade = false;
            protected $_start = false;
            protected $_finish = false;
            protected $_system = false;

            protected $_sql_querys = array();
            protected $_db = false;

        public function __construct($aTrade, $aStart=false, $aFinish=false, $aSystem=false) {
            $this->_trade = $aTrade;

            if( is_int($aStart) ) $this->_start = $aStart;
            else  $this->_start = intval(DateConvert::Date2('U', $aStart));//adodb_date2('U', $aStart));

            if( is_int($aFinish) ) $this->_finish = $aFinish;
            else $this->_finish = intval(DateConvert::Date2('U', $aFinish));//adodb_date2('U', $aFinish));

            $this->_system = $aSystem;
            $this->_db = objDataBase::GetInstance();
            $this->_sqls();
        } //constructor

        public function isValid() {
           $result = $this->_db->handler->GetRow($this->_sql_querys['hangup']);

           return 0===intval($result['Delta']);
        }//isValid

        protected function _sqls() {
            $this->_sql_querys['hangup'] =
                " SELECT ".
                "   t.TradeID, ".
                  //" t.Pair, ".
                  " (( ".
                  "    ( ".
                       " SELECT max(f.BeginTime) ".
                       " FROM vfa_forecast f ".
                       " WHERE f.TradeID=t.TradeID ".
                       ($this->_start?" AND $this->_start<=f.BeginTime":"").
                       ($this->_finish?" AND f.BeginTime<=$this->_finish":"").
                       ($this->_system ? " AND (f.SystemID=$this->_system) " : "").
                       " )-( ".
                       " SELECT max(q.TimeStart) ".
                       " FROM fa_quotes q ".
                       " WHERE q.TradeID=t.TradeID ".
                       ($this->_start ? " AND $this->_start<=q.TimeStart " : "").
                       ($this->_finish ? " AND q.TimeStart<=$this->_finish " : "").

                   " ) ".
                   " )/(4*60*60)>1) AS Delta ".
                " FROM ".
                  " fa_trades t ".
                " WHERE (1=1) ".
                  ($this->_trade ? " AND (t.TradeID=$this->_trade)":"");

        }//_sqls

    } //class StockValidationPeriod
    //-------------------------------------------------------------------------------------------------------
   /*

   */
    //-------------------------------------------------------------------------------------------------------
    //-------------------------------------------------------------------------------------------------------
    //-------------------------------------------------------------------------------------------------------


    //-------------------------------------------------------------------------------------------------------
    class StockManipulaion {

        static public  function isWeekendDay($timestamp) {
            return  0 == intval(DateConvert::Date('w', $timestamp)) ||
                    6 == intval(DateConvert::Date('w', $timestamp)) ;
        }//isWeekendDay

        static public function inInteraval($x, $Xmin, $Xmax, $left=true, $right=false) {
            $result = true;

            if( true==$left ) $result = $result && ($Xmin <= $x);
                else $result = $result && ($Xmin < $x);

            if( true==$right ) $result = $result && ($x <= $Xmax);
                else $result = $result && ($x < $Xmax);

            return $result;
        }//inInteraval

    } //StockManipulation

    //-------------------------------------------------------------------------------------------------------
    class objStockModel extends objObject implements iErrorHandler{
            public $stocks = false;
            public $labels = false;
            public $title = false;
            public $vectors = false;
            public $flags = false;

            public $decimal = false;

            //public $pips = false;
            public $news = false;
            public $stops = false;
            public $trends = false;
            public $year = false;
            public $band_width = 6;
            public $force_weekend = true;

            protected $system_id = false;
            protected $flag_new_forecast = false;
            protected $id = false;
            protected $dx = false;
            protected $_sql_querys = array();
            protected $_trade = false;
            protected $_scale = false;
            protected $_start = false;
            protected $_finish = false;
            protected $_t = false;
            protected $_db = false;
            protected $_original = array();
            protected $_data = false;
            protected $_strong_interval = true;//!!!!!!!!!!!!!!
            protected $_stop_marks = array();
            protected $_pips_marks = array();
            protected $_exact_interval = true;
            protected $_flag_news = false;
            protected $_flag_prepare = false;
            protected $_flag_build = false;
            protected $_error_str = array('no error',//0
                                          'Input parameters are empty',//1
                                          'Data for selected parameters are empty',//2
                                          'Minimal interval beetween xvaluee is 0',//3
                                          'Translation vectors error',//4
                                          'Chosing vectors error - no data',//5
                                          "Can't translate stop marks"//6
                                         );

        public function __construct($trade, $start, $finish, $t=false, $system=false) {
            $this->_trade = $trade;
            $this->_start = $start;
            $this->_finish = $finish;
            $this->_t = $t;

            if (!$this->_trade || !$this->_start || !$this->_finish) throw new Exception($this->Error(1));

            $this->_db = objDataBase::GetInstance();
            $this->system_id = $system;
            $this->_sqls();
        } //constructor

        public function SetSystemID( $aSystemID ){
            $this->system_id = $aSystemID;
            $this->_sqls();
        }//SetSystemID

        public function GetStart() {
            return $this->_start;
        } //GetStart

        public function GetFinish() {
            return $this->_finish;
        } //GetFinish

        public function GetSystem() {
            return $this->system_id;
        }//GetSystem
        //-------------------------------------------------------------------------------------
        public function ClassName() {
            return  __CLASS__;
        }//ClassName
        //-------------------------------------------------------------------------------------
        public function GenID() {
            return $this->id = md5(strval($this->_trade) . strval($this->_start) . strval($this->_finish) . strval($this->_t) . intval($this->system_id));
        } //GenID

        public function GetID() {
            return $this->id;
        } //GetID

        public function Clean() {
            $this->_flag_prepare = false;
            $this->_flag_build = false;
            $this->stocks = false;
            $this->labels = false;
            $this->vectors = false;
            $this->trends = false;
            $this->year = false;
            $this->dx = false;
            $this->_original = array();
            $this->_data = false;
            $this->_sqls();
        } //clean

        public function Prepare($force=false) {
            if( !$this->_flag_prepare || $force) {
                $this->Clean();

                $this->_Stocks();

                $this->_Vectors();

                if( empty($this->stocks) ) throw new Exception($this->_start.' ' .$this->_finish.$this->Error(2));
                if( $this->_flag_news ) $this->_News();
                $this->GenID();
                $this->_flag_prepare = true;
            }
            return true;
        }//prepare

        public function Build($force=false) {
            if( !$this->Prepare($force) ) return false;
            if( !$this->_flag_build || $force) {
                $this->dx =  $this->_DeltaX();
                if( 0==$this->dx )throw new Exception($this->Error(3));

                $this->_Translate();
                if( $this->_flag_news ) $this->_TranslateNews();
                $this->_Labels(); //+
                $this->_Shift();
                $this->_Trends(); //+
                $this->_Stops(); //+
                $this->_Colors();

                if( !$this->_TranslateStopMarks() ) throw new Exception($this->Error(6));
                $this->_TranslatePipsMarks();

                $this->_Scaling();

                $this->_flag_build = true;
            }
        } //Build

        public function StrongInterval($flag=true) {
            $this->_strong_interval = $flag;
        } //StrongInterval

        public function ExactInterval($flag=true) {
            $this->_exact_interval = $flag;
        } //ExactInterval

        public function SetNews($flag=true) {
            $this->_flag_news = $flag;
        } //SetNews

        public function Dump() {
            echo "labels x\n<br>";var_dump($this->labels['x']);
            echo "stocks x\n<br>";var_dump($this->stocks['x']);
            echo "vector s x\n<br>";var_dump($this->vectors['x']);
        } //dump

        public function GetRate() {
            return $this->_db->handler->GetRow($this->_sql_querys['rate'], array($this->_trade));
        }//getRate

        public function GetData($force=false) {
            $this->Build($force);
            $data = array();
            $data['id'] = $this->GenID();
            $data['title'] = $this->title;
            $data['year'] = $this->year;

            $data['decimal'] = $this->decimal;
            $data['stocks'] = $this->stocks;
            $data['labels'] = $this->labels;
            $data['vectors'] = $this->vectors;
            $data['trends'] = $this->trends;
            $data['stops'] = $this->stops;
            //$data['pips'] = $this->pips;
            $data['stop_marks'] = $this->_stop_marks;
            $data['pips_marks'] = $this->_pips_marks;
            $data['scale'] = $this->_scale;
            $data['news'] = $this->news;
            $data['system'] = false;
            if( $this->system_id ){
                $data['system'] = $this->_db->handler->GetRow('SELECT * FROM fa_systems WHERE SystemID=?', array($this->system_id));
            }
            $data['flags'] = $this->flags;
            return $data;
        } //GetData

        public function GetOrigData($force=false) {
             $this->Prepare($force);
             //converting date
             $data = $this->_data;
             for($i=0; $i<count($data['stock'])-1; $i++)
                $data['stock'][$i]['start'] = DateConvert::Date('Y-m-d H:i:s', $data['stock'][$i]['start']);

             for($i=0; $i<count($data['forecast'])-1; $i++)  {
                $data['forecast'][$i]['begin']['time'] = DateConvert::Date('Y-m-d H:i:s', $data['forecast'][$i]['begin']['time']);
             }
             return $data;
        } //GetOrigData

        public function GetPair() {
             return $this->title;
        }//GetPair

        public function GetBeginTime() {
            if( $forecast=$this->GetLastForecast() )
                return $forecast['begin']['otime'];
            else return false;
        }//GetBeginTime

        public function GetBeginPrice() {
            if( $forecast=$this->GetLastForecast() )
                return $forecast['begin']['price'];
            else return false;
        }//GetBeginPrice

        public function GetEndTime() {
            if( $forecast=$this->GetLastForecast() )
                return $forecast['end']['otime'];
            else return false;
        }//GetEndTime

        public function GetEndPrice() {
            if( $forecast=$this->GetLastForecast() )
                return $forecast['end']['price'];
            else return false;
        }//GetEndPrice

        public function GetStopPrice() {
            if( $forecast=$this->GetLastForecast() )
                return $forecast['stop']['price'];
            else return false;
        }//GetStopPrice

        public function GetSide() {
            if( $forecast=$this->GetLastForecast() )
                return $forecast['side'];
            else return false;
        }//GetSide

        public function GetForecastID() {
            if( $forecast=$this->GetLastForecast() )
                return $forecast['id'];
            else return false;
        }//GetForecastID

        public function GetForecast($no, $short=false) {
            $this->Prepare();
            $this->Build();
            $forecast = false;
            if( array_key_exists('forecast', $this->_data) && is_array($this->_data['forecast']) && array_key_exists($no, $this->_data['forecast']) ) {
                $forecast = $this->_data['forecast'][$no];
                if( !$short ) {
                    $forecast['pair'] = $this->GetPair();

                    $forecast['begin']['otime'] = $forecast['begin']['time'];
                    $forecast['end']['otime'] = $forecast['end']['time'];

                    $forecast['begin']['time'] = DateConvert::Date('Y-m-d H:i:s', $forecast['begin']['time']);
                    $forecast['end']['time'] = DateConvert::Date('Y-m-d H:i:s', $forecast['end']['time']);

                    $forecast['color'] = $this->vectors['colors'][$no];
                    //$forecast['stop']['price'] = $forecast['stop']['price'];
                } //if
            }
            return $forecast;
        }//GetForecast


        public function GetForecastByID($id) {
            $result = false;
            for( $no=0; $no<$this->ForecastCount() && !$result; $no++ ) {
                $forecast = $this->GetForecast($no, true);

                if( $id==$forecast['id'] )  $result = $no;
            }
            return (is_int($result) ? $this->GetForecast($result) : false);
        }//GetForecastByID

        public function GetLastForecast() {

            $max=$this->ForecastCount();

            for($no=$max - 1; $no>-1; $no--) {
                $forecast = $this->GetForecast($no);
                if( 3==$forecast['color'] ) return $forecast;
            }
            if( $max>0 ) return $this->GetForecast($max-1);
                else return false;
        } //GetLastForecast


        public function ForecastCount() {
            $this->Prepare();
            if( !array_key_exists('forecast', $this->_data) ) return 0;
            return count($this->_data['forecast']);
        }//ForecastCount

        //---------------------------------------------------------------------------------------------------
        protected function _DeltaX() {
            $delta = array();
            for($i=0; $i<count($this->_original['stock']['x'])-1; $i++)
                $delta[] = abs($this->_original['stock']['x'][$i]-$this->_original['stock']['x'][$i+1]);

            return min($delta);
        } //_DeltaX

        protected function _Scaling() {
            //$maxX = count($this->labels['x'])-1;
            $this->_scale['x']['min'] = 0;
            $this->_scale['x']['max'] = count($this->labels['x'])-1;
            $this->_scale['y']['min'] = false;
            $this->_scale['y']['max'] = false;
        } //_Scaling

        protected function _Shift() {
            for($i=0; $i<count($this->stocks['x']);$i++ ) $this->stocks['x'][$i]++;
            for($i=0; $i<count($this->vectors['x']);$i++ ) $this->vectors['x'][$i]++;

            for($i=0; $i<count($this->_stop_marks);$i++ ) $this->_stop_marks[$i]['x']++;
            for($i=0; $i<count($this->_pips_marks);$i++ ) $this->_pips_marks[$i]['x']++;

            for($i=count($this->labels['x']); $i>0; $i-- )$this->labels['x'][$i] = $this->labels['x'][$i-1];
            for($i=0; $i<count($this->labels['xlines']);$i++ ) $this->labels['xlines'][$i]++;
            for($i=0; $i<count($this->labels['xlines2']);$i++ ) $this->labels['xlines2'][$i]++;
            for($i=0; $i<count($this->labels['xselected']);$i++ ) $this->labels['xselected'][$i]++;
            for($i=0; $i<count($this->news); $i++ ) $this->news[$i]['graph']['x']++;
        } //_Shift

        protected function _Stocks() {
            $data_stocks = $this->_db->handler->GetAll($this->_sql_querys['quotes']);

            $this->title = $data_stocks[0]['Pair'];
            $this->year = $data_stocks[0]['DateYear'];
            $i=0;
            foreach($data_stocks as $item) {
                $this->_original['stock']['x'][] = intval($item['TimeStart']);
                $this->_original['stock']['x_t'][] = intval($item['Time_T']);

                $this->stocks['y'][] = round(floatval($item['O']), 7);
                $this->stocks['y'][] = round(floatval($item['C']), 7);
                $this->stocks['y'][] = round(floatval($item['L']), 7);
                $this->stocks['y'][] = round(floatval($item['H']), 7);

                $this->_data['stock'][$i]['start'] = intval($item['TimeStart']);
                $this->_data['stock'][$i]['open'] = floatval($item['O']);
                $this->_data['stock'][$i]['close'] = floatval($item['C']);
                $this->_data['stock'][$i]['low'] = floatval($item['L']);
                $this->_data['stock'][$i]['high'] = floatval($item['H']);
                $i++;
            }//foreach
        }//_quotes

        protected function _Vectors() {
          global $config;
            if( $this->_strong_interval ) $query = $this->_sql_querys['forecast_strong'];
             else $query = $this->_sql_querys['forecast_soft'];
            //echo $query;//XXX echo query
            $data_vectors = $this->_db->handler->getAll($query);

            $this->decimal = false;
            $this->vectors = array();
            $this->vectors['x'] = array();
            $this->vectors['y'] = array();
            $this->vectors['stop'] = array();
            $i=0;
            foreach($data_vectors as $vector) {
                //-------------------------------------------
                //!!!!!!!!20071208
                //-------------------------------------------
                $forecast_EndTime =  intval($vector['EndTime']);

                if( StockManipulaion::isWeekendDay($forecast_EndTime) ) {

                    //$AlertMailer = new objMailer();
                    //$AlertMailer->AddAddress($config['admin']['email']);
                    //$AlertMailer->isHTML( true );
                    //$AlertMailer->Subject = 'Alert: generated weekend end forecast '.$forecast_EndTime;
                    //$AlertMailer->Body = var_export($vector, true);
                    //$AlertMailer->Send();

                    if( $this->force_weekend ) {
                       while( StockManipulaion::isWeekendDay($forecast_EndTime) ) $forecast_EndTime += 60;
                    }
                } //send alert

                //-------------------------------------------
                $this->vectors['x'][] = intval($vector['BeginTime']);
                $this->vectors['x'][] = $forecast_EndTime;//intval($vector['EndTime']);//!!!!!!!!20071208
                $this->_original['vector'][] = intval($vector['BeginTime']);
                $this->_original['vector'][] = $forecast_EndTime;//intval($vector['EndTime']);//!!!!!!!!20071208

                $this->vectors['y'][] = floatval($vector['BeginPrice']);
                $this->vectors['y'][] = floatval($vector['EndPrice']);
                $this->vectors['stop'][] = floatval($vector['StopPrice']);
                $this->vectors['pip'][] = intval($vector['Pip']);
                $this->vectors['side'][] = intval($vector['Side']);
                $this->vectors['visible'][] = true;//!( $vector['flagEndTime'] && $vector['flagEndPrice'] ) //XXX: all vectors are visible
                $this->vectors['visible_trend'][] = !( $vector['flagEndTime'] && $vector['flagEndPrice'] );
                $this->vectors['visible_trend'][] = !( $vector['flagEndTime'] && $vector['flagEndPrice'] );

                $this->_data['forecast'][$i]['stop'] = array();
                $this->_data['forecast'][$i]['begin'] = array();
                $this->_data['forecast'][$i]['end'] = array();
                $this->_data['forecast'][$i]['close'] = array();
                $this->_data['forecast'][$i]['rate'] = array();
                $this->_data['forecast'][$i]['system'] = array();
                $this->_data['forecast'][$i]['last'] = array();

                $this->_data['forecast'][$i]['id'] = intval($vector['ForecastID']);
                $this->_data['forecast'][$i]['begin']['time'] = intval($vector['BeginTime']);
                $this->_data['forecast'][$i]['begin']['time_formated'] = strval($vector['BeginTimeFormated']);
                $this->_data['forecast'][$i]['active'] = intval($vector['flagActive']);
                $this->_data['forecast'][$i]['pipsize'] = floatval($vector['PipSize']);
/*
                $ti = 0;
                $td = 0.1;
                while( $this->_data['forecast'][$i]['pipsize']<$td ) { $ti++;  $td*=0.1; }

                $this->_data['forecast'][$i]['decimal'] = $ti;
                $this->decimal = $ti;
*/
                // get system neame without "Intelli4x" word in the beginning.
                // system name can contain more then one word so implode the rest
                $sysNameArr = explode(" ",$vector['SystemName']);
                array_shift($sysNameArr);
                $sysNameWord = implode(" ",$sysNameArr);

                if( false===$this->decimal )
                    $this->decimal = NumberConvert::decimal($this->_data['forecast'][$i]['pipsize']);
                $this->_data['forecast'][$i]['decimal'] = $this->decimal;


                $this->_data['forecast'][$i]['begin']['price'] = round(floatval($vector['BeginPrice']), 7);
                $this->_data['forecast'][$i]['end']['time'] = $forecast_EndTime;
                $this->_data['forecast'][$i]['end']['time_formated'] = strval($vector['EndTimeFormated']);
                $this->_data['forecast'][$i]['end']['price'] = round(floatval($vector['EndPrice']), 7);
                $this->_data['forecast'][$i]['color'] = intval($vector['Color']);
                $this->_data['forecast'][$i]['stop']['price'] = floatval($vector['StopPrice']);
                $this->_data['forecast'][$i]['pip'] = intval($vector['Pip']);
                $this->_data['forecast'][$i]['side'] = intval($vector['Side']);
                $this->_data['forecast'][$i]['size'] = floatval($vector['Size']);
                $this->_data['forecast'][$i]['pair'] = strval($vector['Pair']);
                $this->_data['forecast'][$i]['close']['time'] = intval($vector['CloseTime']);
                $this->_data['forecast'][$i]['close']['time_formated'] = strval($vector['CloseTimeFormated']);
                $this->_data['forecast'][$i]['close']['price'] = round(floatval($vector['ClosePrice']), 7);
                $this->_data['forecast'][$i]['close']['reason'] = strval($vector['Reason']);
                $this->_data['forecast'][$i]['last']['time'] = intval($vector['LastTime']);
                $this->_data['forecast'][$i]['last']['price'] = floatval($vector['LastPrice']);

                $this->_data['forecast'][$i]['stop']['pip'] = intval($vector['StopPip']);
                $this->_data['forecast'][$i]['close']['pip'] = intval($vector['ClosePip']);
                $this->_data['forecast'][$i]['end']['pip'] = intval($vector['EndPip']);

                $this->_data['forecast'][$i]['rate']['ask'] = floatval($vector['Ask']);
                $this->_data['forecast'][$i]['rate']['bid'] = floatval($vector['Bid']);
                $this->_data['forecast'][$i]['rate']['unixtime'] = intval($vector['RateTimeUnix']);
                $this->_data['forecast'][$i]['rate']['time_formated'] = strval($vector['RateTimeFormated']);
                $this->_data['forecast'][$i]['rate']['direction'] = intval($vector['Direction']);
                $this->_data['forecast'][$i]['rate']['time'] = strval($vector['RateTime']);

                $this->_data['forecast'][$i]['system']['id'] = strval($vector['SysteID']);
                $this->_data['forecast'][$i]['system']['name'] = strval($vector['SystemName']);
                $this->_data['forecast'][$i]['system']['shortname'] = strval($vector['SystemShortName']);
                $this->_data['forecast'][$i]['system']['nameword'] = strval($sysNameWord);

                $this->_data['forecast'][$i]['flag']['end']['time'] = intval($vector['flagEndTime']);
                $this->_data['forecast'][$i]['flag']['end']['price'] = intval($vector['flagEndPrice']);
                $this->_data['forecast'][$i]['flag']['stop']['price'] = intval($vector['flagStopPrice']);

                $i++;
            } //foreach

        } //_vectors

        protected function _News() {
            $data = $this->_db->handler->getAll($this->_sql_querys['news']);
            $this->news = array(); $index=0;
            foreach($data as $item) {
                $this->news[$index]['no'] = $index + 1;
                $this->news[$index]['id'] = $item['NewsID'];
                $this->news[$index]['country'] = $item['Country'];
                $this->news[$index]['header'] = $item['Header'];
                $this->news[$index]['impact'] = $item['Impact'];
                $this->news[$index]['actual'] = $item['Actual'];
                $this->news[$index]['forecast'] = $item['Forecast'];
                $this->news[$index]['previous'] = $item['Previous'];
                $this->news[$index]['formateddatetime'] = $item['FormatedTimeNews'];
                $this->news[$index]['datetime'] = $item['TimeNews'];
                ++$index;
            } //foreach
            unset($data);
            return !empty($this->news);
        } //News

        public function GetMaxY() {
            $result=0;

            foreach($this->_data['stock'] as $stock ) {
                $result = max($result, $stock['open'], $stock['close'], $stock['low'], $stock['high']);
            } //foreach

            if(!empty($this->_data['forecast']) )
               foreach($this->_data['forecast'] as $forecast ) {
                   $result = max($result, $forecast['begin']['price'], $forecast['end']['price']);
               } //foreach

            return $result;
        } //GetMaxY

        public function GetMinY() {
            $result=0;

            foreach($this->_data['stock'] as $stock ) {
                $result = min($result, $stock['open'], $stock['close'], $stock['low'], $stock['high']);
            } //foreach

            if(!empty($this->_data['forecast']) )
                foreach($this->_data['forecast'] as $forecast ) {
                     $result = min($result, $forecast['begin']['price'], $forecast['end']['price']);
                } //foreach

            return $result;
        } //GetMinY

        protected function _TranslateNews() {
            if( !$this->_flag_news )  return false;
            $news_x=array();
            $nflags=array();
            $dy = 0.002*($this->GetMaxY() - $this->GetMinY());
            for($ni=0; $ni<count($this->news); $ni++ ) {
                $x = $this->news[$ni]['datetime'];
                $nflags[$ni] = false;
                for($si=0; $si<count($this->_original['stock']['x'])-1; $si++ ) {
                    if( $x<$this->_original['stock']['x'][$si] ||
                        StockManipulaion::inInteraval($x, $this->_original['stock']['x'][$si], $this->_original['stock']['x'][$si+1]) ) {

                        $this->news[$ni]['graph']['x'] = $si;
                        $y = max(
                                $this->_data['stock'][$si]['open'],
                                $this->_data['stock'][$si]['close'],
                                $this->_data['stock'][$si]['low'],
                                $this->_data['stock'][$si]['high']);
                        //$this->news[$ni]['graph']['y'] = $y;
                        //------------------------------------------------------------------------------------------------
                        //------------------------------------------------------------------------------------------------
                        //checking if value is uniq
                        //------------------------------------------------------------------------------------------------
                        $j=0; //$y=$this->news[$ni]['graph']['y'];
                        while( $j<$ni ) {
                            if($y==$this->news[$ni]['graph']['y']) {
                                $y+=0.0001;
                                $j=0;
                            }//if
                            ++$j;
                        }//while
                        $this->news[$ni]['graph']['y']=$y+$dy;
                        $nflags[$ni] = true;
                        break;
                     }//if
                    //------------------------------------------------------------------------------------------------
                    // check end of graph
                    //------------------------------------------------------------------------------------------------
                    if( !$nflags[$ni] &&
                        StockManipulaion::inInteraval($x,
                                           $this->_original['stock']['x'][$si],
                                           $this->_original['stock']['x_t'][$si], true, true) ) {
                        //------------------------------------------------------------------------------------------------
                        $this->news[$ni]['graph']['x'] = $si;
                        $y = max(
                                $this->_data['stock'][$si]['open'],
                                $this->_data['stock'][$si]['close'],
                                $this->_data['stock'][$si]['low'],
                                $this->_data['stock'][$si]['high']);
                        //------------------------------------------------------------------------------------------------
                        //checking if value is uniq
                        //------------------------------------------------------------------------------------------------
                        $j=0;
                        while( $j<$ni ) {
                            if( $y==$this->news[$ni]['graph']['y'] ) {
                                $y+=0.0001;
                                $j=0;
                            }//if
                            ++$j;
                        }//while
                        $this->news[$ni]['graph']['y']=$y+$dy;
                        $nflags[$ni] = true;
                    }//end of plot
                }//for stocks
            }//for vectors
            //------------------------------------------------------------------------------------------------
            //grouping news
            //------------------------------------------------------------------------------------------------
            $value=1; $ni=0;
            while( $ni<count($this->news) ) {

                $c=1;
                while( $ni<count($this->news) && $value==$this->news[$ni]['graph']['x']) {
                    $this->news[$ni]['repeat']=$c++;
                    $this->news[$ni]['graph']['y'] += $this->news[$ni]['repeat']*$dy;
                    ++$ni;
                }
                $value=$this->news[$ni]['graph']['x'];
                ++$ni;
            } //while
            //------------------------------------------------------------------------------------------------
            $result = true;
            foreach($nflags as $flag) $result=$result && $flag;
            return $result;
        } //TranslateNews

        protected function getCandleIndex($aValue) {
            $result = false;
            for($si=0; $si<count($this->_original['stock']['x'])-2; $si++ ) {
                if( $aValue < $this->_original['stock']['x'][$si] ||
                   StockManipulaion::inInteraval($aValue,
                                      $this->_original['stock']['x'][$si],
                                      $this->_original['stock']['x'][$si+1]) ) {
                    $result = $si;
                    break;
                }//if
            }//for stocks
            return $result;
        } //getCandleIndex

        protected function getCandleLastIndex() {
            return count($this->_original['stock']['x'])-1;
        } //getCandleLastIndex

        protected function  _TranslateStopMarks() {
            $result = true;
            for($mi=0; $mi<count($this->_stop_marks); $mi++ )
                if( !$this->_stop_marks[$mi]['translated'] ) {
                    $flag_translated = false;

                    if( $index = $this->getCandleIndex($this->_stop_marks[$mi]['x']) ) {
                        $this->_stop_marks[$mi]['x'] = $index+1;

                        $flag_translated = true;
                    } //find candle for stop mark
/*
                    $si = count($this->_original['stock']['x'])-1;
                    if( !$flag ) {

                        if( !StockManipulaion::inInteraval($this->_stop_marks[$mi]['x'],
                                               $this->_original['stock']['x'][$si],
                                               $this->_original['stock']['x_t'][$si], true, true) ) {

                            $this->_stop_marks[$mi]['x'] = $si+1;

                        } else {
                            $this->_stop_marks[$mi]['x'] = $si;//+1;//XXX

                        }

                        $this->_stop_marks[$mi]['translated'] = true;
                        $flag = true;
                    }//end of plot
*/
                    if( !$flag_translated ) {
                        $si = $this->getCandleLastIndex();
                        if( StockManipulaion::inInteraval($this->_stop_marks[$mi]['x'],
                                               $this->_original['stock']['x_t'][$si-1],
                                               $this->_original['stock']['x_t'][$si], false, true) ) {

                            $this->_stop_marks[$mi]['x'] = $si+1;
                        } else {
                            $this->_stop_marks[$mi]['x'] = $si;
                        }
                        $flag_translated = true;
                    } //end of plot
                    $this->_stop_marks[$mi]['translated'] = $flag_translated;

                    $result = $result && $flag_translated;
                } //if not been translated yet

            return $result;
        } //TranslateStopMarks

        protected function  _TranslatePipsMarks() {
            $result = true;
            for($mi=0; $mi<count($this->_pips_marks); $mi++ )
                if( !$this->_pips_marks[$mi]['translated'] ) {
                    $flag = false;

                    if( $index = $this->getCandleIndex($this->_pips_marks[$mi]['x']) ) {
                        $this->_pips_marks[$mi]['x'] = $index+1;
                        $this->_pips_marks[$mi]['translated'] = true;
                        $flag = true;
                    }

                    $si = count($this->_original['stock']['x'])-1;
                    if( !$flag ) {
                        $this->_pips_marks[$mi]['x'] = $si;

                        $this->_pips_marks[$mi]['translated'] = true;
                        $flag = true;
                    }//end of plot

                    $result = $result && $flag;
                } //if not been translated yet
            return $result;
        } //TranslatePipsMarks

        protected function _Translate() {
            $this->stocks['x'] = array_keys($this->_original['stock']['x']);
            //------------------------------------------------------------------
            $vector_x = array();
            $vflags = array();
            for($vi=0; $vi<count($this->vectors['x']); $vi++ ) {
                $x = $this->vectors['x'][$vi];
                $vflags[$vi] = false;
                if( !$x ) {
                    $vector_x[$vi] = $si;
                    $vflags[$vi] = true;
                } //

                if( !$vflags[$vi] ) {
                    if( $index = $this->getCandleIndex($x) ) {
                        $vector_x[$vi] = $index;
                        $vflags[$vi] = true;
                    }//if found candle
                }

                $si = count($this->_original['stock']['x'])-1;
                if( !$vflags[$vi] && $x==$this->_original['stock']['x'][$si]){ //check last candle
                    $vector_x[$vi] = $si;
                    $vflags[$vi] = true;
                }//end of plot
            }//for vectors
            //------------------------------------------------------------------
            $oXstart = $this->_original['stock']['x'][0];
            $wd = 0; //wekend days counter
            $V = array();
            $Vi = 0;
            $V[$Vi++] = max($this->_original['stock']['x']);
            for($vi=0; $vi<count($this->vectors['x']); $vi++ )
              if( false==$vflags[$vi] ) { //not translated yet
                $x = $this->vectors['x'][$vi];
                $si=0; $wd = 0;
                while( true ) {
                    while( StockManipulaion::isWeekendDay($oXstart + $si*$this->dx) &&
                          !StockManipulaion::inInteraval($x, $oXstart + $si*$this->dx, $oXstart + ($si+1)*$this->dx)) {
                        ++$si;
                        ++$wd;
                    }//while  skip weekends days

                    if( $oXstart+$si*$this->dx > $x ||
                        StockManipulaion::inInteraval($x, $oXstart + $si*$this->dx, $oXstart + ($si+1)*$this->dx) ) {
                        //------------------------------------------------------
                        //if choosen intreval is weekend we have to count all that weekend
                        //------------------------------------------------------
                        if( StockManipulaion::isWeekendDay($oXstart + $si*$this->dx) ) {
                                $tsi = $si-1;
                                while( StockManipulaion::isWeekendDay($oXstart + $tsi*$this->dx) ) {
                                        --$tsi;
                                        --$wd;
                                }//while
                        }
                        //------------------------------------------------------
                        $vector_x[$vi] = $si - $wd;
                        $V[$Vi++] = $oXstart + $si*$this->dx;
                        break;
                    } //if
                   $si++;
                }//while
            }//foreach
            //------------------------------------------------------------------
            if( count($this->vectors['x'])!=count($vector_x) )     throw new Exception($this->Error(4));
            //------------------------------------------------------------------
            // build labels
            //------------------------------------------------------------------
            $this->vectors['x'] = $vector_x;
            //------------------------------------------------------------------
            $unix_finish = intval(DateConvert::Date2('U', $this->_finish));
            if ( $this->_exact_interval && (empty($V) || max($V)<$unix_finish) ) {
                $V[] = $unix_finish;//!!!!!!!!!!!
                //	echo "used finish \n";
            }
            $labels_add=array();
            $last_label = 0;
            for( $i=0; $i<count($V)-1; $i++ ) {//!!!!!!!!!!!!!s
                $j=0;
                $fw = StockManipulaion::isWeekendDay($V[$i]) || StockManipulaion::isWeekendDay($V[$i+1]);
                while( $V[$i]+$j*$this->dx <= $V[$i+1] ) {
                    if( $last_label<$V[$i]+$j*$this->dx && (!StockManipulaion::isWeekendDay($V[$i]+$j*$this->dx) || $fw)  ) {
                        $last_label = $V[$i]+$j*$this->dx;
                        $labels_add[] = $last_label;
                    }
                   ++$j;
                } //while
            } //for

            //if( count($V)>0 ) $labels_add[]=$V[count($V)-1];
            //------------------------------------------------------------------
            array_shift($labels_add);
            //------------------------------------------------------------------

            $labels = array_merge(array_diff($this->_original['stock']['x'], $labels_add), $labels_add);
            $labels_add = array();
            //------------------------------------------------------------------
            $maxX = count($labels);
            if( $deltaX = $maxX % $this->band_width ) {
                $deltaX = $this->band_width - $deltaX;//8
                $lastX = $labels[count($labels) - 1];
                for($j=1; $j<=$deltaX; $j++) $labels_add[] = $lastX + $j * $this->dx;
            }
            //------------------------------------------------------------------
            $this->labels['x'] = array_merge(array_diff($labels, $labels_add), $labels_add);
        }//_Translate

        protected function _Colors() {
            if( empty($this->_data) )  throw new Exception($this->Error(5));
            $stocks = $this->_data['stock'];
            if( empty($this->_data['forecast']) )  return;
            $forecasts = $this->_data['forecast'];
            //------------------------------------------------------------------
            // get translated stocks and forecasts
            //------------------------------------------------------------------
            for($j=0; $j<count($stocks); $j++) {
                $stocks[$j]['start'] = $this->stocks['x'][$j];
            }

            $i = 0; $j = 0;
            while( $i < count($forecasts) ) {
                $forecasts[$i]['begin']['time'] = $this->vectors['x'][$j];
                $forecasts[$i]['end']['time']   = $this->vectors['x'][$j+1];
                $j+=2; $i++;
            }//while
            //------------------------------------------------------------------
            $max_stock_time = $stocks[count($stocks)-1]['start'];
            $this->flag_new_forecast = false;
            //------------------------------------------------------------------
            $mark_index = 0;
            $this->_stop_marks = array();
            $this->_pips_marks = array();
            $colors = array();
            $flags = array();
            for($i=0; $i<count($forecasts); $i++)  {
                $forecast = $forecasts[$i];
                $colors[$i] = $forecast['color'];
                $flags[$i] = false;

                if( $colors[$i]>0 && $forecast['close']['time'] ) {
                    $this->_stop_marks[$mark_index]['x'] = $forecast['close']['time'];
                    $this->_stop_marks[$mark_index]['y'] = $forecast['close']['price'];
                    $this->_stop_marks[$mark_index]['translated'] = false;
                } else {
                    $this->_stop_marks[$mark_index]['x'] = $forecast['last']['time'];
                    $this->_stop_marks[$mark_index]['y'] = $forecast['last']['price'];
                    $this->_stop_marks[$mark_index]['translated'] = false;
                }

                $this->_pips_marks[$mark_index]['x'] = $forecast['end']['time'];
                $this->_pips_marks[$mark_index]['y'] = $forecast['end']['price'];
                $this->_pips_marks[$mark_index]['translated'] = true;

                if( !$colors[$i] )  $colors[$i] = 3;
                $this->_stop_marks[$mark_index]['color'] = $colors[$i];
                $this->_stop_marks[$mark_index]['pip'] = $forecast['pip'];
                $this->_stop_marks[$mark_index]['side'] = $forecast['side'];

                $this->_pips_marks[$mark_index]['color'] = $colors[$i];
                $this->_pips_marks[$mark_index]['pip'] = $forecast['pip'];
                $this->_pips_marks[$mark_index]['side'] = $forecast['side'];
                $this->_pips_marks[$mark_index]['active'] = $forecast['active'];

                ++$mark_index;
                if( 3==$colors[$i] ) $this->flag_new_forecast = true;
                unset($forecast);

            } //for each forecast

            $this->vectors['colors'] = $colors;
            $this->vectors['flag_colors'] = $flags;
            unset($stocks);
            unset($forecasts);
        } //_Colours

        public function isNewForecast() {
            return $this->flag_new_forecast;
        } //isNewForecast

        protected function _Trends() {
            $this->trends = array();
            $i=0; $j=0;
            while ( $i < count($this->vectors['x'])-1 ) {
                if( $this->vectors['visible_trend'][$i] ) {
                    $this->trends[$j]['x'] = array(intval($this->vectors['x'][$i]), intval($this->vectors['x'][$i+1]));
                    $this->trends[$j++]['y'] = array(floatval($this->vectors['y'][$i+1]), floatval($this->vectors['y'][$i+1]));
                } //if
                $i+=2;
            } //foreach
        } //_Trends

        protected function _Stops() {
            $this->stops = array();
            $i=0; $j=0; $c=0;
            while ( $i < count($this->vectors['x'])-1 ) {
                if( $this->_data['forecast'][$c]['stop']['price']>0 ) {
                    $this->stops[$j]['x'] = array(intval($this->vectors['x'][$i]), intval($this->vectors['x'][$i+1]));
                    $this->stops[$j++]['y'] = array(floatval($this->_data['forecast'][$c]['stop']['price']),
                                                    floatval($this->_data['forecast'][$c]['stop']['price']));
                } //if
                else {
                    $this->stops[$j]['x'] = false;
                    $this->stops[$j++]['y'] = false;
                }
                $i+=2;
                ++$c;
            } //while
        } //_Stops

        protected function _Labels() {
            $md=''; $hm='';
            $result=array();
            $borders=array(); $wborders=array(); $iborder=0;
            $major = array();
            $selected = array();
            $flag_weekend = false;
            $wod=false;$pwod=false;

            foreach($this->labels['x'] as $label) {
                $wod=DateConvert::Date('w', $label);
                if( $wod != $pwod && (5==$pwod || 1==$wod) ) {
                    $wborders[]=$iborder;
                }
                if(6!==$wod && 0!==$wod) $pwod = $wod;

                $tmd = DateConvert::Date('M j', $label);
                $result[]='';
                if( $tmd!==$md ) {
                    $md=$tmd;
                    $borders[]=$iborder;
                }
                $major[] = $iborder;
                ++$iborder;
            }

            $major[] = $iborder;
            $borders[] = $iborder;
            $i=0;
            while( $i<count($borders)-1 ) {
                $j = round(0.5*($borders[$i+1] - $borders[$i]) + $borders[$i]);
                $result[$j]=DateConvert::Date('M j', $this->labels['x'][$j]);

                $wod = DateConvert::Date('w', $this->labels['x'][$j]);
                if( 0==$wod || 1==$wod || 5==$wod || 6==$wod ) $selected[] = intval($j);

                ++$i;
            }
            if( !empty($borders) )$major[] = $borders[count($borders)-1];
            $this->labels['x'] = $result;
            $this->labels['xmajor'] = $major;
            $this->labels['xselected'] = $selected;
            $this->labels['xlines'] = $borders;
            $this->labels['xlines2'] = $wborders;
        } //_Labels

        protected function _sqls() {
            $this->_sql_querys['quotes'] =
            "SELECT ".
                "t.Pair, ".
                "t.TradeID, ".
                "t.Pipsize, ".
                "q.TimeStart, ".
                "q.Time_T, ".
                "from_unixtime(q.`TimeStart`,'%Y')as DateYear, ".
                "q.O, ".
                "q.H, ".
                "q.L, ".
                "q.C ".
            "FROM ".
                "fa_quotes q ".
                "LEFT OUTER JOIN fa_trades t ON (q.TradeID = t.TradeID) ".
            "WHERE t.TradeId=$this->_trade ".
                        " AND FROM_UNIXTIME(q.TimeStart,'%Y-%m-%d') between '$this->_start' and '$this->_finish' ".
            "ORDER BY ".
                "t.TradeID, ".
                "q.TimeStart ";
            //------------------------------------------------------------------
            $where_systemid = '';
            if( $this->system_id ) $where_systemid = ' AND f.SystemID = ' . $this->system_id. ' ';
            //------------------------------------------------------------------
            $this->_sql_querys['forecast_main'] =
                "SELECT f.ForecastID, f.BeginPrice, f.BeginTime,t.TradeID,t.Pair, t.PipSize, f.Color, f.Side,  f.Size, " .
                    " f.StopPrice, ".
                    " f.Reason, ".

                    " f.CloseTime is null AS flagActive, ".
                    " (f.EndTime is Null ) AS flagEndTime, ".
                    " (f.EndPrice is Null ) AS flagEndPrice, ".
                    " (f.StopPrice is Null ) AS flagStopPrice, ".

                    " COALESCE(f.EndPrice, f.BeginPrice+(1 - 2 * f.Side)*0.3*dq.DeltaPriceQuote) AS EndPrice, " .

                    " lq.LastCloseTime as LastTime, " .
                    " lq.LastPrice as LastPrice, ".

                    "f.CloseTime, ".

                    " round((1 - 2 * f.Side) * (COALESCE(f.ClosePrice, (1-f.Side)* r.Bid + f.Side*r.Ask, lq.LastClosePrice) - f.BeginPrice) / t.PipSize) as Pip, ".
                    " COALESCE(round( (1 - 2 * f.Side) * (f.StopPrice - f.BeginPrice) / t.PipSize ), 0) as StopPip, ".
                    " COALESCE(round( (1 - 2 * f.Side) * (f.EndPrice - f.BeginPrice) / t.PipSize ), 0) as EndPip, ".
                    " COALESCE(round( (1 - 2 * f.Side) * (f.ClosePrice - f.BeginPrice) / t.PipSize ), 0) as ClosePip, ".

                    " r.Ask, ".
                    " r.Bid, ".
                    " r.Time as RateTimeUnix, ".
                    " r.Direction, ".
                    " r.RateTime, ".
                    " from_unixtime(r.Time,'%I:%i %p GMT') as RateTimeFormated, ".

                    " s.`Name` as `SystemName`, ".
                    " s.ShortName as SystemShortName, ".
                    " s.SystemID, " .

                    " COALESCE(f.ClosePrice, lq.LastClosePrice) as ClosePrice,   ".
                    " COALESCE(f.EndTime, f.CloseTime, f.BeginTime+s.ViewPeriod, lq.LastCloseTimeT) as EndTime, ".
                    " from_unixtime(f.BeginTime, '%Y-%m-%d %I:%i %p GMT') as BeginTimeFormated, ".
                    " from_unixtime(COALESCE(f.EndTime, f.CloseTime, f.BeginTime+s.ViewPeriod, lq.LastCloseTimeT), '%Y-%m-%d %I:%i %p GMT') as EndTimeFormated, ".//20090109 Close->End
                    " from_unixtime(COALESCE(f.CloseTime, lq.LastCloseTime), '%Y-%m-%d %I:%i %p GMT') as CloseTimeFormated ".
                    //" from_unixtime(f.EndTime, '%Y-%m-%d %I:%i %p GMT') as EndTimeFormated, ". //2090109
                    //" from_unixtime(COALESCE(f.EndTime, f.CloseTime, GREATEST(f.BeginTime+s.TimeFrame, lq.LastCloseTimeT)), '%Y-%m-%d %I:%i %p GMT') as CloseTimeFormated, ".
                "FROM vfa_forecast f ".
                       " LEFT OUTER JOIN fa_trades t ON (f.TradeID = t.TradeID) ".
                       " LEFT OUTER JOIN fa_systems s ON (f.SystemID = s.SystemID) ".
                       " LEFT OUTER JOIN  ".
                            " (SELECT *, FROM_UNIXTIME(tr.`Time`, '%Y-%m-%d %H:%i:%s') as RateTime FROM fa_rates tr ) r ".
                            " ON (f.TradeID=r.TradeID) ".

                       " LEFT OUTER JOIN " .
                        " ( " .
                         " SELECT " .
                              " ttq.TradeID, " .
                              " ttq.C as LastClosePrice, " .
                              " GREATEST(ttq.O, ttq.C, ttq.H, ttq.L) as LastPrice, ".
                              " ttq.TimeStart as LastCloseTime, " .
                              " ttq.Time_T as LastCloseTimeT ".
                         " FROM fa_quotes ttq " .
                             " RIGHT OUTER JOIN ( " .
                                   " SELECT tq.TradeID, max(tq.TimeStart) as max_quote_time " .
                                   " FROM fa_quotes tq " .
                                   " GROUP BY tq.TradeID) qq " .
                                   " ON (qq.max_quote_time=ttq.TimeStart and qq.TradeID=ttq.TradeID) " .
                        ") lq " .
                        "ON (f.TradeID = lq.TradeID), " .
                        " ( ".
                          " SELECT ".
                            " MAX(GREATEST(tdq.O, tdq.C, tdq.H, tdq.L)) as MaxPriceQuote, ".
                            " MIN(LEAST(tdq.O, tdq.C, tdq.H, tdq.L)) as MinPriceQuote, ".
                            " MAX(GREATEST(tdq.O, tdq.C, tdq.H, tdq.L)) - ".
                                " MIN(LEAST(tdq.O, tdq.C, tdq.H, tdq.L)) as DeltaPriceQuote ".
                          " FROM fa_quotes tdq ".

                          " WHERE tdq.TradeId=$this->_trade ".
                                " AND FROM_UNIXTIME(tdq.TimeStart,'%Y-%m-%d') between '$this->_start' and '$this->_finish' ".
                        " ) AS dq ".
                        "WHERE (1=1)";
            //------------------------------------------------------------------
            $this->_sql_querys['forecast_soft'] =
                $this->_sql_querys['forecast_main'] .
                " AND t.TradeId=$this->_trade AND FROM_UNIXTIME(f.BeginTime,'%Y-%m-%d') between '$this->_start' and '$this->_finish'" . $where_systemid .
             " ORDER BY COALESCE(f.CloseTime, f.EndTime, f.BeginTime+s.ViewPeriod, lq.LastCloseTimeT)";

            $this->_sql_querys['forecast_strong'] =
                $this->_sql_querys['forecast_main'] .
                "AND t.TradeId=$this->_trade ".
                  " AND FROM_UNIXTIME(f.BeginTime,'%Y-%m-%d') between '$this->_start' and '$this->_finish'".
                    " AND FROM_UNIXTIME(COALESCE(f.EndTime, f.CloseTime, f.BeginTime+s.ViewPeriod, lq.LastCloseTimeT),'%Y-%m-%d') between '$this->_start' and '$this->_finish' " .
                  $where_systemid .
             " ORDER BY COALESCE(f.CloseTime, f.EndTime, f.BeginTime+s.ViewPeriod, lq.LastCloseTimeT)";

            //------------------------------------------------------------------
            $this->_sql_querys['news'] =
             " SELECT ".
                 " td.TradeID AS TradeID, ".
                 " n.fx_news_id AS NewsID, ".
                 " n.fx_news_country AS Country, ".
                 " n.fx_news_header AS Header, ".
                 " n.fx_news_impact AS Impact, ".
                 " n.fx_news_actual AS Actual, ".
                 " n.fx_news_forecast AS Forecast, ".
                 " n.fx_news_previous AS Previous, ".
                 " n.fx_news_date AS FormatedTimeNews, ".
                 " TimeNews ".
             " FROM ".
                 " fa_trade_country td ".
                   " left join fa_news n on (td.Country = n.fx_news_country) ".
                   " left join fa_trades t on (td.TradeID = t.TradeID) ".
             " WHERE td.TradeID=$this->_trade AND ".
                   " TimeNews ".
                   " BETWEEN UNIX_TIMESTAMP('$this->_start') AND UNIX_TIMESTAMP('$this->_finish') ".
             " ORDER BY  ".
             " TimeNews ";
            //------------------------------------------------------------------
            $this->_sql_querys['rate'] =
                           "SELECT *, FROM_UNIXTIME(r.`Time`, '%Y-%m-%d %I:%i:%s') as RateTime FROM fa_rates r WHERE r.TradeID=? ORDER BY r.SortIndex";

        } //sqls
    } //class objStockModel
    //---------------------------------------------------------------------------------------------------

    class objForecastView {
            protected  $_data = false;
            protected $_sql_querys = array();
            protected $_id = false;

        public function __construct($aID=false) {
            $this->SetID($aID);

            $this->_sqls();
        }//constructor

        public function __set($name, $value) {
            $name = strtolower($name);
            switch( $name ) {
                case 'id':
                    $this->SetID($value);
                break;
            }//switch
        } //setter

        public function __get($name) {
            if( array_key_exists($name, $this->_data) ) return $this->_data[$name];

            $name = strtolower($name);
            switch( $name ) {
                case 'id':
                    return $this->_id;
                break;
            }//switch

        } //getter

        public function Get($aID=false) {
            if( $aID ) $this->SetID($aID);
            return $this->_data = objDataBase::GetInstance()->handler->GetRow($this->_sql_querys['forecast_by_id'], array($this->_id));
        }//get

        public function Load($aID=false) {
            return $this->Get($aID);
        }//Load

        public function SetID($aID=false) {
            $this->_id = intval($aID);
        }//SetID

        protected function _sqls() {
            //------------------------------------------------------------------
            $this->_sql_querys['forecast_main'] =
            "SELECT f.ForecastID, f.BeginPrice, f.BeginTime,f.EndTime, t.TradeID,t.Pair, t.Pipsize, f.Color, f.Side, f.Size, " .
                " f.StopPrice, ".
                " f.CloseTime is null AS flagActive, ".
                " (f.EndTime is Null) AS flagEndTime, ".
                " (f.EndPrice is Null) AS flagEndPrice, ".
                " (f.StopPrice is Null) AS flagStopPrice, ".

                " lq.LastCloseTime as LastTime, " .
                " lq.LastPrice as LastPrice, ".

                " COALESCE(f.CloseTime,lq.LastCloseTime) as CloseTime,   ".
                " COALESCE(f.ClosePrice,lq.LastClosePrice) as ClosePrice,   ".
                //" COALESCE(f.EndTime, f.CloseTime, GREATEST(f.BeginTime+s.TimeFrame, lq.LastCloseTimeT)) as EndTime, ".//f.BeginTime+60*60*24
                " COALESCE(f.EndTime, f.CloseTime, f.BeginTime+s.ViewPeriod, lq.LastCloseTimeT) as EndTime, ".//f.BeginTime+60*60*24


                //" COALESCE(f.EndPrice, f.BeginPrice+(1 - 2 * f.Side)*0.3*dq.DeltaPriceQuote) AS EndPrice, " .

                " round((1 - 2 * f.Side) * (COALESCE(f.ClosePrice, (1-f.Side)* r.Bid + f.Side*r.Ask, lq.LastClosePrice) - f.BeginPrice) / t.PipSize) as Pip, ".

                " COALESCE(round( (1 - 2 * f.Side) * (f.StopPrice - f.BeginPrice) / t.PipSize ), 0) as StopPip, ".
                " COALESCE(round( (1 - 2 * f.Side) * (f.EndPrice - f.BeginPrice) / t.PipSize ), 0) as EndPip, ".
                " COALESCE(round( (1 - 2 * f.Side) * (f.ClosePrice - f.BeginPrice) / t.PipSize ), 0) as ClosePip, ".

                " r.Ask, ".
                " r.Bid, ".
                " r.Time as RateTimeUnix, ".
                " r.Direction, ".
                " r.RateTime, ".
                " s.`Name` as `SystemName`, ".
                " s.ShortName as SystemShortName, ".
                " s.SystemID, " .
                " s.ChartPeriod, s.TimeFrame, s.ViewPeriod,".

                " from_unixtime(f.BeginTime, '%Y-%m-%d %I:%i %p GMT') as BeginTimeFormated, ".
                " from_unixtime(COALESCE(f.CloseTime,lq.LastCloseTime), '%Y-%m-%d %I:%i %p GMT') as CloseTimeFormated, ".
                //" from_unixtime(COALESCE(f.EndTime, f.CloseTime, GREATEST(f.BeginTime+s.TimeFrame, lq.LastCloseTimeT)), '%Y-%m-%d %I:%i %p GMT') as EndTimeFormated, ".
                " from_unixtime(COALESCE(f.EndTime, f.CloseTime, f.BeginTime+s.ViewPeriod, lq.LastCloseTimeT), '%Y-%m-%d %I:%i %p GMT') as EndTimeFormated, ".
                " from_unixtime(r.Time,'%I:%i %p GMT') as RateTimeFormated, ".

                " f.BeginTime as BeginForecast, ".
                " COALESCE(f.EndTime, f.CloseTime, f.BeginTime+s.ViewPeriod, lq.LastCloseTime) as EndForecast ".

            "FROM vfa_forecast f ".
                    " LEFT OUTER JOIN fa_trades t ON (f.TradeID = t.TradeID) ".
                    " LEFT OUTER JOIN fa_systems s ON (f.SystemID = s.SystemID) ".
                    " LEFT OUTER JOIN  ".
                        " (SELECT *, FROM_UNIXTIME(tr.`Time`, '%Y-%m-%d %H:%i:%s') as RateTime FROM fa_rates tr) r ".
                        " ON (f.TradeID=r.TradeID) ".

                    " LEFT OUTER JOIN " .
                    " ( " .
                     " SELECT " .
                          " ttq.TradeID, " .
                          " ttq.C as LastClosePrice, " .
                          " GREATEST(ttq.O, ttq.C, ttq.H, ttq.L) as LastPrice, ".
                          " ttq.TimeStart as LastCloseTime, " .
                          " ttq.Time_T as LastCloseTimeT ".
                     " FROM fa_quotes ttq " .
                         " RIGHT OUTER JOIN ( " .
                               " SELECT tq.TradeID, max(tq.TimeStart) as max_quote_time " .
                               " FROM fa_quotes tq " .
                               " GROUP BY tq.TradeID) qq " .
                               " ON (qq.max_quote_time=ttq.TimeStart and qq.TradeID=ttq.TradeID) " .

                    ") lq " .

                    "ON (f.TradeID = lq.TradeID) ";
            //------------------------------------------------------------------
            $this->_sql_querys['forecast_by_id'] = $this->_sql_querys['forecast_main'] .
                    " WHERE f.ForecastID=? ";
            //------------------------------------------------------------------

            $this->_sql_querys['forecast_by_id'] .=
                //" ORDER BY COALESCE(f.CloseTime, f.EndTime, GREATEST(f.BeginTime+s.TimeFrame, lq.LastCloseTimeT))";
                " ORDER BY COALESCE(f.CloseTime, f.EndTime, f.BeginTime+s.ViewPeriod, lq.LastCloseTimeT)";
        }//_sqls
    }//class ForecastView
//-------------------------------------------------------------------------------------------------------
?>
